﻿using System.Collections.Generic;
using System.Linq;

namespace AutomatedDecisionMaking.Class.Algorithms
{
    class MiniMaxAlgorithm
    {
        private readonly DecisionMatrix _mDecisionMatrix;    /// Macierz decyzji
        private readonly List<string> _mStrListMinValue;     /// Najmniejsze wartości w rzędach wraz z decyzjami
        private readonly List<double> _mListMinValue;        /// Najmniejsze wartości w rzedach
        private double _mMiniMaxVal;                         /// Najmniejsza z najmnijeszych wartości
        private string _mDecision;                           /// Podjęta decyzja

        /// <summary>
        /// Konstruktor algorytmu realizującego kryterium MiniMax.
        /// </summary>
        /// <param name="decisionMatrix">Macierz decyzji wprowadzona porzez użytkownika</param>
        public MiniMaxAlgorithm(DecisionMatrix decisionMatrix)
        {
            _mStrListMinValue = new List<string>();
            _mListMinValue = new List<double>();
            _mDecisionMatrix = decisionMatrix;
        }

        /// <summary>
        /// Uruchomienie algorytmu i rozwiązanie postawionego zadania
        /// </summary>
        public void CalculateSolution()
        {
            //List<double> listMinValue = new List<double>();
            for (int i = 0; i < _mDecisionMatrix.Value.Count; ++i)
            {
                string element = _mDecisionMatrix.DecisionList.ElementAt(i);
                double minVal = _mDecisionMatrix.Value[i].Min();
                _mStrListMinValue.Add(element + " : min = "+ minVal);
                _mListMinValue.Add(minVal);
            }

            _mMiniMaxVal = _mListMinValue.Min();
            _mDecision = _mDecisionMatrix.DecisionList.ElementAt(_mListMinValue.FindIndex(w => w == _mMiniMaxVal));
        }

        /// <summary>
        /// Pobranie podjętej decyzji
        /// </summary>
        /// <returns>Podjęta decyzja</returns>
        public string GetDecision()
        {
            return _mDecision;
        }

        /// <summary>
        /// Pobranie najmniejszej z najmniejszych wartości
        /// </summary>
        /// <returns>Najmniejsza z najmniejszych wartość</returns>
        public double GetMiniMaxValue()
        {
            return _mMiniMaxVal;
        }

        /// <summary>
        /// Lista najmniejszych wartości w rzędach wraz z decyzjami
        /// </summary>
        /// <returns>NAjmniejsze wartości w rzędach</returns>
        public List<string> GetMinValuesStr()
        {
            return _mStrListMinValue;
        }

        /// <summary>
        /// Lista najmniejszych wartości w rzędach wraz
        /// </summary>
        /// <returns>NAjmniejsze wartości w rzędach</returns>
        public List<double> GetMinValues()
        {
            return _mListMinValue;
        }
    }
}
